package com.rytong.tools.parserwidgets;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.rytong.tools.ui.Component;
import com.rytong.tools.utils.Utils;

public final class ParseWidgets extends DefaultHandler {
    Attributes atts_;
    // 触发的事件类型
    int eventType_;
    final int START_DOCUMENT = 0;
    final int END_DOCUMENT = 1;
    final int START_TAG = 2;
    final int END_TAG = 3;
    final int TEXT = 4;

    // 读取中间节点值的次数
    int readTextIndex_;

    // 存储节点值
    StringBuffer buf_;
    // 控件初始对象名
    String keyName_;
    // 判断节点是否有值
    boolean isHasValue_;

    LPWidgets widgets_;

    static HashMap WIDGETSLIST;

    // XML开始解析时调用此方法
    public void startDocument() throws SAXException {
        eventType_ = START_DOCUMENT;
        WIDGETSLIST = new HashMap();
    }

    // 解析到Element的开头时调用此方法
    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
        eventType_ = START_TAG;
        // 将读取节点值次数标记复位
        readTextIndex_ = 0;
        // 赋值节点属性
        atts_ = atts;
        if (localName.equalsIgnoreCase("Object")) {
            widgets_ = new LPWidgets();
            widgets_.setClass(getAttrString("class"));
            widgets_.setInit(getAttrString("init"));
            widgets_.setTag(getAttrString("tag"));
            widgets_.setType(getAttrString("type"));
        } else if (localName.equalsIgnoreCase("param")) {
            keyName_ = getAttrString("key");
        }
    }

    // 取得Element的中间夹的字符串
    public void characters(char ch[], int start, int length) {
        if (eventType_ == END_TAG && length > 1) {
            // 如果紧接着end_tag后面有需要获取出来的数据则执行
            readTextIndex_ = 0;
        }
        try {
            eventType_ = TEXT;
            if (readTextIndex_ == 0) {
                // 节点计数器为零表示是第一次读取该节点值。应将以前读取的值全部清空。该处执行赋空操作，如果执行delete操作数据量大的话会引起内存溢出问题。
                buf_ = null;
                buf_ = new StringBuffer();
                // 该判断条件保证每个节点只进入一次，可以规避从子节点返回父节点也要执行该方法带来的不便。
                // 进入该方法表示该节点有值（存在子节点或者存在节点值）
                // 进入每个节点都会进入该判断条件
                this.isHasValue_ = true;
            }
            // 读取节点值
            buf_.append(ch, start, length);
            // 节点值计数器累加
            readTextIndex_++;

        } catch (Exception e) {
            // TODO Auto-generated catch block
            Utils.printException(e);
        }
    }

    // 解析到Element的结尾时调用此方法
    public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
        eventType_ = END_TAG;
        // 还原节点是否有值标记位
        isHasValue_ = false;
        // 赋值节点属性
        atts_ = null;
        if (localName.equalsIgnoreCase("param")) {
            String text = Utils.insteadOfSpecillCharacter(buf_.toString().trim(), false);
            widgets_.setAttr(keyName_, text);
            keyName_ = "";
        } else if (localName.equalsIgnoreCase("object")) {
            // 控件并不都是以tag属性来区分,有些tag属性相同,还要根据type属性来区分(例如input类控件)
            String nameType = widgets_.getType();
            if (null == nameType)
                nameType = "";
            WIDGETSLIST.put(widgets_.getTag().concat("-").concat(nameType), widgets_);
        }
    }

    // XML解析结束时调用此方法
    public void endDocument() throws SAXException {
        eventType_ = END_DOCUMENT;
        widgets_ = null;
    }

    /**
     * @param attrName
     * @return
     */
    private final String getAttrString(String attrName) {
        String attr = null;
        try {
            attr = Utils.insteadOfSpecillCharacter(atts_.getValue(attrName), false);
        } catch (Exception e) {
            Utils.printException(e);
        }
        return attr;
    }

    public static Object initWidget(String tagname) {
        Class temp = null;
        Component o = null;
        // 根据控件名取得对应的控件配置
        LPWidgets widget = (LPWidgets) WIDGETSLIST.get(tagname);
        if (null != widget) {
            String className = widget.getClassName();
            try {
                // 根据类名取得对应的类应的类
                temp = Class.forName(className);
                o = (Component)temp.newInstance();
                o.initWithParam();

                final int size = widget.attrs_.size();
                if (size > 0) {
                    o.attributes_ = widget.attrs_;
                    o.widgetType_ = widget.getType();
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                Utils.printException(e);
            }
        }
        return o;
    }
}
